/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014年7月31日
 * V4.0
 */
package com.jphenix.kernel.script;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.jphenix.driver.json.Json;
import com.jphenix.driver.threadpool.ThreadSession;
import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.kernel.objectloader.FBeanFactory;
import com.jphenix.service.db.datamanager.interfaceclass.IDataManager;
import com.jphenix.servlet.multipart.instancea.UploadFile;
import com.jphenix.share.lang.SBoolean;
import com.jphenix.share.lang.SListMap;
import com.jphenix.share.lang.SString;
import com.jphenix.share.tools.FileCopyTools;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.share.util.SFilesUtil;
import com.jphenix.share.util.StringUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.viewhandler.IViewHandler;

/**
 * 脚本类处理工具
 * 
 * 2019-02-15 修改了拼装sql语句时的错误
 * 2019-03-07 修改了拼装语句错误
 * 2019-08-02 fixSqlStr方法最后一个参数，增加了强制不使用语句段功能
 * 2019-09-18 又尝试解析除去//注释，结果失败（太复杂，不划算）,已经加好注释，避免又再尝试解析
 * 2019-11-06 支持在复杂语句段<%S S%>中，支持简单方法插入语句段变量 <@*sqlSubVar@>
 * 2019-12-12 增加了可以在脚本中直接使用的方法
 * 2022-02-08 不能采用Class.forName方式构建类，因为要构建的类所在的包可能不在 /WEB-INF/classes 中，可能在其子文件夹中
 * 2024-07-04 将fixMap方法中的返回值从HashMap改为LinkedHashMap
 * 
 * @author 马宝刚
 * 2014年7月31日
 */
@ClassInfo({"2024-07-04 10:58","脚本类处理工具"})
public class ScriptUtil {

	
	/**
	 * 处理Map参数信息
	 * @param keys 		传入参数主键
	 * @param values	传入参数值
	 * @return 			整理后的传入参数
	 * 2019年12月12日
	 * @author 马宝刚
	 */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public static Map fixMap(String[] keys,Object[] values){
    	//构造返回值
    	Map reMap = new LinkedHashMap();
    	if(keys!=null && values!=null) {
    		for(int i=0;i<keys.length;i++) {
    			reMap.put(keys[i],values[i]);
    		}
    	}
    	return reMap;
    }
    
	/**
	 * 处理Map参数信息
	 * @param keys 		传入参数主键
	 * @param values	传入参数值
	 * @param reMap 	返回值对象
	 * @return 			整理后的传入参数
	 * 2014年8月22日
	 * @author 马宝刚
	 */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public static Map fixMap(String[] keys,Object[] values,Map reMap){
    	//构造返回值
    	if(reMap==null) {
    		reMap = new LinkedHashMap();
    	}
    	if(keys!=null && values!=null) {
    		for(int i=0;i<keys.length;i++) {
    			reMap.put(keys[i],values[i]);
    		}
    	}
    	return reMap;
    }
    
    /**
     * 处理List参数信息
     * @param values 传入参数数组
     * @return       返回值对象
     * 2019年12月12日
     * @author MBG
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static List fixList(Object[] values) {
    	//构建返回值
    	List reList = new ArrayList();
    	if(values!=null) {
    		for(Object obj:values) {
    			reList.add(obj);
    		}
    	}
    	return reList;
    }
    
    
    /**
     * 处理List参数信息
     * @param values	传入参数数组
     * @param reList 	返回值对象
     * @return	处理后的参数
     * 2014年8月22日
     * @author 马宝刚
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public static List fixList(Object[] values,List reList){
    	//构造返回值
    	if(reList==null) {
    		reList = new ArrayList();
    	}
    	if(values!=null) {
    		for(Object obj:values) {
    			reList.add(obj);
    		}
    	}
    	return reList;
    }
    
    
	/**
	 * 处理SListMap参数信息
	 * @param keys 		传入参数主键
	 * @param values	传入参数值
	 * @return 			整理后的传入参数
	 * 2019年12月12日
	 * @author 马宝刚
	 */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public static SListMap fixSListMap(String[] keys,Object[] values){
    	//构造返回值
    	SListMap reMap = new SListMap();
    	if(keys!=null && values!=null) {
    		for(int i=0;i<keys.length;i++) {
    			reMap.put(keys[i],values[i]);
    		}
    	}
    	return reMap;
    }
    
	/**
	 * 处理SListMap参数信息
	 * @param keys 		传入参数主键
	 * @param values	传入参数值
	 * @param reMap		返回值对象
	 * @return 			整理后的传入参数
	 * 2014年8月22日
	 * @author 马宝刚
	 */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public static SListMap fixSListMap(String[] keys,Object[] values,SListMap reMap){
    	//构造返回值
    	if(reMap==null) {
    		reMap = new SListMap();
    	}
    	if(keys!=null && values!=null) {
    		for(int i=0;i<keys.length;i++) {
    			reMap.put(keys[i],values[i]);
    		}
    	}
    	return reMap;
    }

	/**
	 * 通过脚本中定义的类型代码获取对应的类型
	 * @param typeName 类型代码
	 * @return 对应的类型
	 * 2014年7月31日
	 * @author 马宝刚
	 */
	public static Class<?> getTypeCls(String typeName){
		if(typeName==null) {
			return null;
		}
		if("String".equalsIgnoreCase(typeName)) {
			return String.class;
		}
		if("String[]".equalsIgnoreCase(typeName)) {
			return String[].class;
		}
		if("int".equalsIgnoreCase(typeName)) {
			return int.class;
		}
		if("int[]".equalsIgnoreCase(typeName)) {
			return int[].class;
		}
		if("long".equalsIgnoreCase(typeName)) {
			return long.class;
		}
		if("long[]".equalsIgnoreCase(typeName)) {
			return long[].class;
		}
		if("double".equalsIgnoreCase(typeName)) {
			return double.class;
		}
		if("double[]".equalsIgnoreCase(typeName)) {
			return double[].class;
		}
		if("float".equalsIgnoreCase(typeName)) {
			return float.class;
		}
		if("float[]".equalsIgnoreCase(typeName)) {
			return float[].class;
		}
		if("boolean".equalsIgnoreCase(typeName)) {
			return boolean.class;
		}
		if("boolean[]".equalsIgnoreCase(typeName)) {
			return boolean[].class;
		}
		if("Map".equalsIgnoreCase(typeName)) {
			return Map.class;
		}
		if("List".equalsIgnoreCase(typeName)) {
			return List.class;
		}
		if("UploadFile".equalsIgnoreCase(typeName)
				|| "file".equals(typeName)
				|| typeName.equals(UploadFile.class.getName())) {
			return UploadFile.class;
		}
		if("UploadFile[]".equalsIgnoreCase(typeName)
				|| "file[]".equalsIgnoreCase(typeName)
				|| typeName.equalsIgnoreCase(UploadFile.class.getName()+"[]")) {
			return UploadFile[].class;
		}
		if("IViewHandler".equalsIgnoreCase(typeName)){
			return IViewHandler.class;
		}
		if("Json".equalsIgnoreCase(typeName)) {
			return Json.class;
		}
		if(typeName.endsWith("[]")) {
		    try {
		    	return java.lang.reflect.Array.newInstance(
		    			FBeanFactory.getBeanFactory().getClassLoader().loadClass(
		    					typeName.substring(0,typeName.length()-2))).getClass();
		    	//不能采用Class.forName方式构建类，因为要构建的类所在的包可能不在 /WEB-INF/classes 中，可能在其子文件夹中
		        //return java.lang.reflect.Array.newInstance(Class.forName(typeName.substring(0,typeName.length()-2))).getClass();
		    }catch(Exception e) {
		        e.printStackTrace();
		    }
		}else{
		      try {
		    	    return FBeanFactory.getBeanFactory().getClassLoader().loadClass(typeName);
		            //return Class.forName(typeName);
		        }catch(Exception e) {
		            e.printStackTrace();
		        }
		}
		return Object.class;
	}
	
	
	/**
	 * 删除指定路径，并符合文件名头的文件
	 * @param filePath 文件全路径/文件名头
	 * @param reserveJavaFile 是否保留java文件
	 * 2014年8月25日
	 * @author 马宝刚
	 */
	public static void deleteScript(String filePath,boolean reserveJavaFile) {
		if(filePath==null || filePath.length()<1) {
			return;
		}
		if((new File(filePath)).isDirectory()) {
			//很危险，不能删除文件夹
			return;
		}
        //原文件根路径
        String fileBasesPath = SFilesUtil.getFilePath(filePath,false);
        //获取文件名开头
        String fileHead = SFilesUtil.getFileName(filePath);
        
        List<String> fileList = new ArrayList<String>(); //搜索到的文件信息
        try {
            SFilesUtil.getFileList(fileList,fileBasesPath,fileHead,null,false,false);
        }catch(Exception e) {
            e.printStackTrace();
            return;
        }
        for(String elePath:fileList) {
        	if(reserveJavaFile && elePath.toLowerCase().endsWith(".java")) {
        		continue;
        	}
            try {
                SFilesUtil.deletePath(elePath);
            }catch(Exception e) {
                e.printStackTrace();
            }
        }
    
	}
	
	
	/**
	 * 将文件从一个地方移动到另外一个地方
	 * 
	 * srcPath  路径/文件名开头
	 * 
	 * 将原文件路径中符合文件开头的文件，都移动到目标路径中
	 * 
	 * 
	 * @param srcPath	原路径（包含文件开头（不完整的文件名））
	 * @param objPath	目标路径（不包含文件夹名）
	 * 2014年8月25日
	 * @author 马宝刚
	 */
	public static void moveScript(String srcPath,String objPath) {
		//原文件根路径
		String srcBasesPath = SFilesUtil.getFilePath(srcPath,false);
		objPath = SFilesUtil.getFilePath(objPath,false); //去掉文件名
		
		//获取文件名开头
		String fileHead = SFilesUtil.getFileName(srcPath);
		
		List<String> fileList = new ArrayList<String>(); //搜索到的文件信息
		try {
			SFilesUtil.getFileList(fileList,srcBasesPath,fileHead,null,false,true);
		}catch(Exception e) {
			e.printStackTrace();
			return;
		}
		String allFilePath; //文件全路径
		for(String filePath:fileList) {
			allFilePath = SFilesUtil.getAllFilePath(filePath,srcBasesPath);
			try {
				FileCopyTools.copyFilePath(allFilePath,objPath,null);
			}catch(Exception e) {
				e.printStackTrace();
			}
			try {
				SFilesUtil.deletePath(allFilePath);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 建立事务
	 * @param key 事务主键
	 * 2015年11月23日
	 * @author 马宝刚
	 */
	@SuppressWarnings("unchecked")
    public static void createDbTransaction(String key,ABase base) {
	    base.log("-----------------------Begin Create Transaction Key:["+key+"]");
	    //获取会话主键序列优先顺序由小到大
	    List<String> _dbTransactionKeyList = (List<String>)ThreadSession.get("_db_transaction_");
	    if(_dbTransactionKeyList==null){
	        _dbTransactionKeyList = new ArrayList<String>();
	        ThreadSession.put("_db_transaction_",_dbTransactionKeyList);
	    }
	    _dbTransactionKeyList.add(0,key);
	}
	
	/**
	 * 提交数据事务
	 * @param key 事务主键
	 * @param base 基类（用于写日志，获取数据库连接池）
	 * 2015年11月23日
	 * @author 马宝刚
	 */
	public static void commitDbTransaction(String key,ABase base) {
        if(base==null) {
            return;
        }
        if(!base.getBeanFactory().beanExists(IDataManager.class)) {
            base.warning("~~~~~~~~~没有发现数据库连接池");
            return;
        }
        base.log("-----------------------Begin Commit Transaction Key:["+key+"]");
        try {
            IDataManager dm = base.getBean(IDataManager.class); //数据库管理类
            dm.commit(key); //执行提交
        }catch(Exception e) {
            e.printStackTrace();
        }
	}
	
	/**
	 * 回滚数据事务
     * @param key 事务主键
     * @param base 基类（用于写日志，获取数据库连接池）
	 * 2015年11月23日
	 * @author 马宝刚
	 */
	public static void rollbackDbTransaction(String key,ABase base){
        if(base==null) {
            return;
        }
        if(!base.getBeanFactory().beanExists(IDataManager.class)) {
            base.warning("~~~~~~~~~没有发现数据库连接池");
            return;
        }
        base.log("-----------------------Begin RollBack Transaction Key:["+key+"]");
        try {
            IDataManager dm = base.getBean(IDataManager.class); //数据库管理类
            dm.rollback(key); //执行提交
        } catch(RuntimeException ex) {
            	
        }catch(Exception e) {
            e.printStackTrace();
        }
	}
	
	/**
     * 关闭数据事务
     * @param key 事务主键
     * @param base 基类（用于写日志，获取数据库连接池）
	 * 2015年11月23日
	 * @author 马宝刚
	 */
	@SuppressWarnings("unchecked")
    public static void closeDbTransaction(String key,ABase base) {
        if(base==null) {
            return;
        }
        if(!base.getBeanFactory().beanExists(IDataManager.class)) {
            base.warning("~~~~~~~~~没有发现数据库连接池");
            return;
        }
        base.log("-----------------------Begin Close Transaction Key:["+key+"]");
        //获取会话主键序列优先顺序由小到大
        List<String> _dbTransactionKeyList = (List<String>)ThreadSession.get("_db_transaction_");
        if(_dbTransactionKeyList!=null){
            _dbTransactionKeyList.remove(key);
        }
        try {
            IDataManager dm = base.getBean(IDataManager.class); //数据库管理类
            dm.close(key); //执行提交
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
	
	/**
	 * 拼装Sql语句段  如果提交值不为空，则返回sql语句段
	 * 如果语句段中包含问号，则返回提交值
	 * 
	 * 无需增加参数判断是否将提交值放入提交值序列，还只是用来判断语句段是否存在
	 * 只要语句段中存在问号，就保存提交值。反之只用来判断语句段是否存在
	 * 
	 * @param sqlSub sql语句段
	 * @param params 提交值
	 * @return 处理后的语句段和提交值
	 * @throws Exception 异常
	 * 2017年1月21日
	 * @author MBG
	 */
	public static Object[] fixSqlSub(String sqlSub,Object params) throws Exception {
		return fixSqlSub(sqlSub,params,0);
	}
	
	/**
	 * 拼装Sql语句段  如果提交值不为空，则返回sql语句段
	 * 如果语句段中包含问号，则返回提交值
	 * 
	 * 无需增加参数判断是否将提交值放入提交值序列，还只是用来判断语句段是否存在
	 * 只要语句段中存在问号，就保存提交值。反之只用来判断语句段是否存在
	 * 
	 * @param sqlSub sql语句段
	 * @param params 提交值
	 * @param need   如果提交值为空，是否强制提交该值  true强制提交  false强制不提交
	 * @return 处理后的语句段和提交值
	 * @throws Exception 异常
	 * 2017年1月21日
	 * @author MBG
	 */
	public static Object[] fixSqlSub(String sqlSub,Object params,boolean need) throws Exception {
		return fixSqlSub(sqlSub,params,need?1:2);
	}
	
	/**
	 * 拼装Sql语句段  如果提交值不为空，则返回sql语句段
	 * 如果语句段中包含问号，则返回提交值
	 * 
	 * 无需增加参数判断是否将提交值放入提交值序列，还只是用来判断语句段是否存在
	 * 只要语句段中存在问号，就保存提交值。反之只用来判断语句段是否存在
	 * 
	 * @param sqlSub sql语句段
	 * @param params 提交值
	 * @param need   如果提交值为空，是否强制提交该值   0自动判断  1强制提交   2强制不提交
	 * @return 处理后的语句段和提交值
	 * @throws Exception 异常
	 * 2017年1月21日
	 * @author MBG
	 */
	@SuppressWarnings({"unchecked" })
	public static Object[] fixSqlSub(String sqlSub,Object params,int need) throws Exception {
		if(sqlSub==null) {
			sqlSub = "";
		}
		if(need==2) {
			need   = 0;
			params = null;
		}
		//构造返回值
		Object[] reObjs = new Object[2]; 
		if(params==null) {
			if(need==1) {
				//强制提交值
				reObjs[0] = sqlSub;
				reObjs[1] = null;
			}else {
				reObjs[0] = "";
				reObjs[1] = null;
			}
			return reObjs;
		}
		if(params instanceof String) {
			//传入参数为字符串
			if((((String)params).length()<1 
					|| "%".equals(params)
					|| "%%".equals(params)) && need==0){
				reObjs[0] = "";
				reObjs[1] = null;
				return reObjs;
			}
			reObjs[0] = sqlSub;
			if(sqlSub.indexOf("?")>-1) {
				reObjs[1] = params;
			}else {
				reObjs[1] = null;
			}
			return reObjs;
		}
		if(params instanceof List) {
			//list，专门针对in类型的语句段 (?,?,?,?)
			List<String> paraList = (List<String>)params;
			if(paraList.size()<1) {
				//没有提交值
				if(need==1) {
					if(sqlSub.indexOf("*")>-1) {
						//原本是返回 '' 但这样做没必要，因为这样查不到任何数据
						//这种逻辑跟传入空字符串时，忽略该语句段保持一致
						reObjs[0] = "";
					}else {
						reObjs[0] = sqlSub;
					}
				}else {
					reObjs[0] = "";
				}
				reObjs[1] = null;
				return reObjs;
			}
			if(sqlSub.indexOf("*")>-1) {
				sqlSub = BaseUtil.swapString(sqlSub,"*",StringUtil.list2DbProp(paraList));
			}
			reObjs[0] = sqlSub;
			if(sqlSub.indexOf("?")>-1) {
				reObjs[1] = paraList;
			}else {
				reObjs[1] = null;
			}
			return reObjs;
		}
		//全部转换成字符串处理
		reObjs[0] = sqlSub;
		if(sqlSub.indexOf("?")>-1) {
			reObjs[1] = SString.valueOf(params);
		}else {
			reObjs[1] = null;
		}
		return reObjs;
	}
	
	
	/**
	 * 除去脚本代码中的全部注释
	 * @param content 脚本内容代码
	 * @return 全部注释
	 * 2017年1月21日
	 * @author MBG
	 */
	public static String fixZs(String content) {
		if(content==null) {
			return "";
		}
		/*
		 * 去掉  / *  * / 这种类型的注释
		 */
		int p1 = content.indexOf("/*");			//开头的 /* 注释开始
		int p2 = content.indexOf("/*",p1+2);    //判断是否存在嵌套注释
		int p3 = content.indexOf("*/",p1);      //注释结束符
		int p4;                                 //临时值
		while(p1>-1) {
			if(p3<0) {
				break;
			}
			if(p2>-1 && p2<p3) {
				//存在注释嵌套，即： /*   /*内注释*/   */
				//如果按照常规找到内注释的结束符，后面的结束符就解析报错了
				
				p4 = content.lastIndexOf("/*",p3);
				if(p4==p2) {
					//当前p3就是p2内嵌套的结束符
					p3 = content.indexOf("*/",p3+2);
					p2=p3; //避免再进入这里
				}else if(p2<p4) {
					p3 = content.indexOf("*/",p3+2);
					//去掉这个嵌入的起始符
					content = content.substring(0,p4)+"**"+content.substring(p4+2);
				}else {
					//绝对不存在p2>p4
				}
				continue;
			}else {
				//正常解析
				if(p1>0) {
					//去掉中间注释
					content = content.substring(0,p1)+content.substring(p3+2);
				}else {
					//最开头就是注释
					content = content.substring(p3+2);
				}
			}
			p1 = content.indexOf("/*");
			p2 = content.indexOf("/*",p1+2);
			p3 = content.indexOf("*/",p1);
		}
		
		/*
		 * 去掉 //这种类型的注释
		 * 
		 * 放弃：不能去掉这种注释，因为容易跟字符串中的这个值混淆，还得判断是不是在字符串中，非常麻烦
		 * 
		 * 在字符串中出现的该字符 String url = "http://www.test.com"; 
		 */
		/*
		p1 = content.indexOf("//");
		while(p1>-1) {
			p2 = content.indexOf("\n",p1);
			if(p2<0) {
				content = content.substring(0,p1);
			}else {
				content = content.substring(0,p1)+content.substring(p2+1);
			}
			p1 = content.indexOf("//");
		}
		*/
		return content;
	}
	
	
    /**
     * 处理SQL转义字符串
     * @param sqlContent  SQL内容
     * @param paraMap     待提交参数
     * @return 处理后的内容（数据库操作类传入的参数）
     * @throws Exception 异常
     * 2017年1月21日
     * @author MBG
     */
    public static Object[] fixSqlStr(String sqlContent,Map<String,String> paraMap) throws Exception {
        //语句段序列
        List<Object> sqlSubList = new ArrayList<Object>();
        //<@变量名  #注释>
        int sPoint = sqlContent.indexOf("<@");          //变量定义开始
        int ePoint = sqlContent.indexOf("@>" ,sPoint);   //变量定义结束
        int tPoint; //临时节点
        String fixSub;   //转译变量名
        String sqlVar;   //复杂语句段中的提交值
        String booVar;   //第三个参数   一段返回布尔型的表达式
        while(sPoint>-1 && ePoint>0) {
        	
        	fixSub = sqlContent.substring(sPoint+2,ePoint);
    		//"",var,boolean
    		fixSub = BaseUtil.trim(fixSub," ","\t","\r","\n");
    		
        	if(fixSub.startsWith("*")) {
        		//<@*subSqlVar@>   其中 subSqlVar 是一个变量，其值是sql语句段
        		sqlSubList.add(fixSub.substring(1));
        	}else {
        		//动态标识符为  <@"",ar,boolean@> 为复杂sql设置值
                tPoint = fixSub.indexOf("#");
                if(tPoint>-1) {
                	fixSub = BaseUtil.trim(fixSub.substring(0,tPoint)," ","\t","\r","\n");
                }
        		if(sPoint>0) {
            		//放入之前的语句段信息
            		sqlSubList.add(BaseUtil.swapString(sqlContent.substring(0,sPoint),"\"","\\\"","《","<","》",">"));
        		}
        		tPoint = fixSub.lastIndexOf(","); //语句段与传入参数的分隔符
        		if(tPoint>0) {
        			sqlVar = BaseUtil.trim(fixSub.substring(tPoint+1)," ","\t");
        			fixSub = BaseUtil.trim(fixSub.substring(0,tPoint)," ","\t","\r","\n","\"");
        			
        			//检查是否有三个参数
        			tPoint = fixSub.lastIndexOf(","); //语句段与传入参数的分隔符
        			if(tPoint>0) {
        				//三个参数 :
        				//1: sql语句段（其中包含?问号,代表传入值 )
        				//2:传入值变量名  （如果该值为空或空字符串，并且第三个参数为false，则不使用该语句段）
        				//3：是否强制使用该语句段（如果该值为false，并且传入值为空，则不使用该语句段）
        				booVar = sqlVar;
            			sqlVar = BaseUtil.trim(fixSub.substring(tPoint+1)," ","\t");
            			fixSub = BaseUtil.trim(fixSub.substring(0,tPoint)," ","\t","\r","\n");
            			sqlSubList.add(new String[] {fixSub,sqlVar,booVar});
        			}else {
        				//传入了两个参数  
        				//1：sql语句段（其中需要包含?符号，代表传入值）
        				//2：传入值变量名，如果该值为空（或空字符串）则不使用这个语句段
            			sqlSubList.add(new String[] {fixSub,sqlVar});
        			}
        		}else {
        			//只传入了一个参数：传入值变量名，这种模式会在这处语句段自动增加?符号
        			sqlSubList.add(new String[] {"\"?\"",fixSub,"1"});
        		}
        	}
    		sqlContent = sqlContent.substring(ePoint+2);
            sPoint = sqlContent.indexOf("<@");
            ePoint = sqlContent.indexOf("@>",sPoint);
        }
        if(sqlContent.length()>0) {
        	sqlSubList.add(BaseUtil.swapString(sqlContent,"\"","\\\"","《","<","》",">"));
        }
        //构建返回值
        List<Object> resList = new ArrayList<Object>();
        for(Object ele:sqlSubList) {
        	 //为了避免解析错误，字符串中的半角大于号、小于号都写成全角的  解析过程时，被改回半角的
        	//去掉了换行符，是因为sql语句中如果包含换行符就报错
        	if(ele instanceof String) {
        		//常规Sql字符串
        		resList.add(BaseUtil.swapString(((String)ele),"《","<","》",">","\r","\\r","\n","\\n"));
        	}else {
        		//为 String[]类型    0语句段   1提交参数值变量  2是否强制提交该值 （类型为整型或布尔型）
        		if(((String[])ele).length>2) {
            		resList.add(
                  		  fixSqlSub(
                  		     BaseUtil.swapString(((String[])ele)[0],"，",","       ,"《","<"         ,"》",">"        ,"\r","\\r"       ,"\n","\\n")
                  		    ,SString.valueOf(paraMap.get(BaseUtil.swapString(((String[])ele)[1],"，",",").trim()))
                  		    ,SBoolean.valueOf(BaseUtil.swapString(((String[])ele)[2],"，",",").trim())
                  		  )
                  		);
        		}else {
        			resList.add(
            		  fixSqlSub(
                   		     BaseUtil.swapString(((String[])ele)[0],"，",","       ,"《","<"         ,"》",">"        ,"\r","\\r"       ,"\n","\\n")
                   		    ,SString.valueOf(paraMap.get(BaseUtil.swapString(((String[])ele)[1],"，",",").trim()))
                   	  )
            		);
        		}
        	}
        }
        return resList.toArray();
    }
}
